package com.zhj.jvm.test.classload;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * @author zhj
 */
public class MyClassLoaderImpl extends ClassLoader {

    private String path = null;

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    // 默认是系统加载器
    public MyClassLoaderImpl() {
        super();
    }

    // 可以干预加载器
    public MyClassLoaderImpl(ClassLoader classLoader) {
        super(classLoader);
    }

    public Class findClass(String name) {
        System.out.println(name);
        System.out.println("findClass...");
        byte[] b = loadClassData(name);
        if (b != null) {
            return defineClass(name, b, 0, b.length);
        }
        return null;
    }

    private byte[] loadClassData(String name) {
        if (path != null) {
            name = path + name.substring(name.lastIndexOf(".") + 1) + ".class";
        } else {
            name = dotToSplit("target.classes." + name) + ".class";
        }
        File file = new File(name);
        byte[] bytes = null;
        if (file.exists()) {
            FileInputStream fileInputStream = null;
            ByteArrayOutputStream outputStream = null;
            try {
                fileInputStream = new FileInputStream(file);
                outputStream = new ByteArrayOutputStream();
                byte[] buf = new byte[1024];
                int len = -1;
                while ((len = fileInputStream.read(buf)) != -1) {
                    outputStream.write(buf, 0, len);
                }
                bytes = outputStream.toByteArray();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (fileInputStream != null) {
                        fileInputStream.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    if (outputStream != null) {
                        outputStream.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return bytes;
    }

    public static String dotToSplit(String className){
        return className.replace(".","/") ;
    }

    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        MyClassLoaderImpl myClassLoad = new MyClassLoaderImpl();
        // Class<?> myClass = myClassLoad.loadClass("com.zhj.jvm.test.classload.MyDefineCL");
        myClassLoad.setPath("E:\\data_file\\");
        Class<?> myClass = myClassLoad.loadClass("com.zhj.jvm.test.classload.MyDefineCL");
        System.out.println(myClass.getClassLoader());
        System.out.println(myClass.getName());
        /*MyDefineCL o = (MyDefineCL) (myClass.newInstance());
        o.say();*/
    }
}

